home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2000 / MacHack 2000.toast / pc / The Hacks / Softshoe / Lisa's Portable Parts / Patterns / MatchLoop.cp next >
Encoding:
Text File  |  2000-06-23  |  2.7 KB  |  115 lines

  1. // MatchLoop.cp
  2.  
  3. #ifndef MatchLoop_h
  4. #include "MatchLoop.h"
  5. #endif
  6. #ifndef PatternMatcher_h
  7. #include "PatternMatcher.h"
  8. #endif
  9. #ifndef Overflow_h
  10. #include "Overflow.h"
  11. #endif
  12.  
  13. bool MatchLoop::Matching() const
  14.   {
  15.     Assert( matchEnd > source.Start() );
  16.     Assert( matchEnd <= source.End() );
  17.     Assert( pattern->Target().End() > pattern->Target().Start() );
  18.     
  19.     const uint8 *sourcePosition = matchEnd;
  20.     const uint8 *targetPosition = pattern->Target().End();
  21.     
  22.     if ( Asuint32( matchEnd - source.Start() ) < pattern->Length() )
  23.       {
  24.         do
  25.             if ( *--sourcePosition != *--targetPosition )
  26.                 return false;
  27.          while ( sourcePosition > source.Start() );
  28.         
  29.         Assert( matchedPrefix >= Asuint32( targetPosition - pattern->Target().Start() ) );
  30.         sourcePosition = pattern->Target().Start() + matchedPrefix;
  31.       }
  32.  
  33.     do
  34.         if ( *--sourcePosition != *--targetPosition )
  35.             return false;
  36.      while ( targetPosition > pattern->Target().Start() );
  37.     
  38.     return true;
  39.   }
  40.  
  41. bool MatchLoop::PartiallyMatching() const
  42.   {
  43.     Assert( matchEnd > source.End() );
  44.     Assert( matchEnd >= source.Start() + pattern->Length() );
  45.     Assert( matchEnd <= source.End() + pattern->Length() );
  46.     
  47.     const uint8 *sourcePosition = matchEnd - pattern->Length();
  48.     const uint8 *targetPosition = pattern->Target().Start();
  49.     
  50.     while ( sourcePosition < source.End()
  51.           && targetPosition < pattern->Target().End() )
  52.         if ( *sourcePosition++ != *targetPosition++ )
  53.             return false;
  54.     
  55.     return true;
  56.   }
  57.  
  58. void MatchLoop::Advance()
  59.   {
  60.     Assert( matchEnd >= source.Start() + pattern->Target().Length() - matchedPrefix );
  61.  
  62.     for ( ; Unfinished(); matchEnd += pattern->Advance( matchEnd[-1] ) )
  63.         if ( Matching() )
  64.             return;
  65.     
  66.     uint32 targetLength = pattern->Target().Length();
  67.     for ( const uint8 *p = source.End(); p > matchEnd - targetLength; p-- )
  68.       {
  69.         const uint8 *possibleEnd = p + pattern->Advance( p[-1] );
  70.         if ( possibleEnd > matchEnd )
  71.             matchEnd = possibleEnd;
  72.       }
  73.     
  74.     while ( !PartiallyMatching() )
  75.         matchEnd++;
  76.     
  77.     matchedPrefix = pattern->Length() - ( matchEnd - source.End() );
  78.   }
  79.  
  80. MatchLoop::MatchLoop( const PatternMatcher& thePattern )
  81.   : pattern( &thePattern ),
  82.      matchEnd( 0 ),
  83.      matchedPrefix( 0 )
  84.   {
  85.   }
  86.  
  87. MatchLoop::MatchLoop( const PatternMatcher& thePattern, ConstData firstSource )
  88.   : pattern( &thePattern ),
  89.      source( firstSource ),
  90.      matchEnd( firstSource.Start() + pattern->Length() ),
  91.      matchedPrefix( 0 )
  92.   {
  93.     Advance();
  94.   }
  95.  
  96. void MatchLoop::Start( ConstData theSource )
  97.   {
  98.     source = theSource;
  99.     matchEnd = source.Start() + pattern->Length();
  100.     Advance();
  101.   }
  102.  
  103. void MatchLoop::Continue( ConstData theSource )
  104.   {
  105.     source = theSource;
  106.     matchEnd = source.Start() + pattern->Length() - matchedPrefix;
  107.     Advance();
  108.   }
  109.  
  110. void MatchLoop::operator++()
  111.   {
  112.     matchEnd += pattern->Advance( matchEnd[-1] );
  113.     Advance();
  114.   }
  115.